package com.test33_反射;

import org.junit.Test;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;

/**
 * 反射调用方法
 */
public class Demo07_Method {

    /**
     * getMethods()，获取类中所有public方法(包含父类)
     * getDeclaredMethods()，获取本类的所有方法(不包含父类)
     */
    @Test
    public void test1() throws Exception {
        Class<?> clazz = Class.forName("com.test33_反射.Book7");
        Method[] methods = clazz.getMethods();
        // Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }

    /**
     * 获取方法的定义信息
     */
    @Test
    public void test2() throws Exception {
        Class<?> clazz = Class.forName("com.test33_反射.Book7");
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.print(Modifier.toString(method.getModifiers()) + " ");   // 获取方法修饰符
            System.out.print(method.getGenericReturnType() + " ");  // 获取返回值类型
            System.out.print(method.getName() + "("); // 获取方法名称
            Type[] parameterTypes = method.getGenericParameterTypes();  // 获取参数列表
            for (int x = 0; x < parameterTypes.length; x++) {
                System.out.print(parameterTypes[x].getTypeName() + " arg" + x);
                if (x < parameterTypes.length - 1) {
                    System.out.print(", ");
                }
            }
            System.out.print(")");
            Type[] exceptions = method.getGenericExceptionTypes();  // 获取所有异常
            if (exceptions.length > 0) {
                System.out.print(" throws ");
                for (int x = 0; x < exceptions.length; x++) {
                    System.out.print(exceptions[x].getTypeName());
                    if (x < exceptions.length - 1) {
                        System.out.print(", ");
                    }
                }
            }
            System.out.println();
        }
    }

    /**
     * 通过反射调用方法
     */
    @Test
    public void test3() throws Exception {
        {
            Book7 book = new Book7();
            book.setTitle("Java从入门到项目实战");
            System.out.println(book.getTitle());
        }
        {
            String fieldName = "title";
            String fieldValue = "Java从入门到项目实战";
            Class<?> clazz = Class.forName("com.test33_反射.Book7");
            Object object = clazz.getDeclaredConstructor().newInstance();   // 反射实例化对象
            // 获取set方法，并调用
            Method setMethod = clazz.getMethod("set" + initcap(fieldName), String.class);
            setMethod.invoke(object, fieldValue);
            // 获取get方法，并调用
            Method getMethod = clazz.getMethod("get" + initcap(fieldName));
            System.out.println(getMethod.invoke(object));
        }
    }

    /** 首字符大写 */
    public static String initcap(String str) {
        if (str == null || "".equals(str)) {
            return str;
        }
        if (str.length() == 1) {
            return str.toUpperCase();
        } else {
            return str.substring(0, 1).toUpperCase() + str.substring(1);
        }
    }
}

class Book7 {
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void read() throws RuntimeException {
    }
}
